package edu.gatech.cs2340.OregonTrail;

import javax.swing.JOptionPane;

import edu.gatech.cs2340.OregonTrail.EventSystem.AtLocationEvent;
import edu.gatech.cs2340.OregonTrail.EventSystem.AtRiverEvent;
import edu.gatech.cs2340.OregonTrail.EventSystem.CommCoordinator;
import edu.gatech.cs2340.OregonTrail.EventSystem.WinEvent;

/**
 * It's documenting time!!!!! This has just been freaking documented!!!
 *
 */
public class Trail {
	
	private Region currentRegion;
	private int milesTraveled;
	//private boolean fork1; 
	//private boolean fork2;
	private Location[] locations = new Location[13];
	private River[] rivers = new River[3];
	private Location currentLocation;
	private int locationIndex;
	private River currentRiver;
	private int riverIndex;
	private CommCoordinator comm;
	
	
	public Trail(CommCoordinator comm)
	{
		this.comm = comm;
		currentRegion = null;
		//fork1 = false;
		//fork2 = false;
		milesTraveled = 0;
		locationIndex = 0;
		riverIndex = 0;
		
		locations[0] = new Location("Fort Karney", 304, null, true, comm);
		locations[1] = new Location("Chimney Rock", 554, null, false, comm);
		locations[2] = new Location("Fort Laramie", 640, null, true, comm);
		locations[3] = new Location("Independence Rock", 830, null, false, comm);
		locations[4] = new Location("South Pass", 932, null, false, comm);
		locations[5] = new Location("Fort Bridger", 1057, null, true, comm);
		locations[6] = new Location("Soda Springs", 1219, null, false, comm);
		locations[7] = new Location("Fort Hall", 1276, null, true, comm);
		locations[8] = new Location("Fort Boise", 1572, null, true, comm);
		locations[9] = new Location("Blue Mountains", 1734, null, false, comm);
		locations[10] = new Location("Fort Walla Walla", 1789, null, true, comm);
		locations[11] = new Location("Dalles", 1909, null, true, comm);
		locations[12] = new Location("Oregon", 2000, null, false, comm);
		
		rivers[0] = new River("Kansas River", 102, 7);
		rivers[1] = new River("Big Blue", 182, 2);
		rivers[2] = new River("Snake River", 1458, 5);
	}
	
	public River[] getRiver()
	{
		return rivers;
	}
	
	/**
	 * Method to determine player's current location, if any, given miles traveled.
	 * @return the current player's Location or river, or null if player is on the trail.
	 */
	public Object getCurrentLocation(int milesTraveled)
	{
		for (Location loc : locations)
		{
			if (loc.getDistance() == milesTraveled) return loc;
		}
		for (River riv : rivers)
		{
			if (riv.getDistance() == milesTraveled) return riv;
		}
		return null;
	}
	
	public Location[] getLocations()
	{
		return locations;
	}
	
	public void setRivers(River[] rivers)
	{
		this.rivers = rivers;
	}
	
	public void setLocations(Location[] locations)
	{
		this.locations = locations;
	}
	
	/**
	 * @return the currentRegion
	 */
	public Region getCurrentRegion() {
		return currentRegion;
	}

	/**
	 * @param currentRegion the currentRegion to set
	 */
	public void setCurrentRegion(Region r) {
		currentRegion = r;
	}
	
	public int getMilesTraveled(){
		return milesTraveled;
	}
	
	public void setMilesTraveled(int miles)
	{
		milesTraveled = miles;
	}

	public int getRiverIndex()
	{
		return riverIndex;
	}
	
	public int getLocationIndex()
	{
		return locationIndex;
	}
	
	public void setRiverIndex(int index)
	{
		riverIndex = index;
	}
	
	public void setLocationIndex(int index)
	{
		locationIndex = index;
	}
	
	public void advance(PlayerInventory pi, SettingManager sm, Party party, final Game game){
		Item oxen = new Item();
		oxen.setItemName("An ox");
		int numOxen = pi.getStock().get(oxen);
		if (numOxen > 0){
			int miles = 0;
			if (sm.getPace() == ePace.low) miles = 5;
			else if (sm.getPace() == ePace.medium) miles = 10;
			else if (sm.getPace() == ePace.high) miles = 15;
			milesTraveled += miles;
		}
		
		int numAlive = 5;
		for (int i = 0; i < 4; i++){
			if (party.getParty().get(i).getStatus() == eStatus.dead) numAlive--;
		}
		
		int mult = 1;
		if (sm.getRations() == eRation.low) mult = 1;
		if (sm.getRations() == eRation.medium) mult = 2;
		if (sm.getRations() == eRation.high) mult = 3;
		int foodDeduction = mult * numAlive;
				
		
		Item foodItem = new Item();
		foodItem.setItemName("Food");
		foodItem.setWeight(1);
		pi.removeItem(foodItem, foodDeduction);
		game.setDay(game.getDay()+1);
		
		if(riverIndex < 3 && rivers[riverIndex].getVisited() == false && rivers[riverIndex].getDistance() <= milesTraveled){
			currentRiver = rivers[riverIndex];
			milesTraveled = currentRiver.getDistance();
			currentRiver.setVisited(true);
			riverIndex++;
			comm.ThrowGUIEvent(new AtRiverEvent(currentRiver));
		}
		if(locationIndex < 13 && locations[locationIndex].getVisited() == false && locations[locationIndex].getDistance() <= milesTraveled){
			currentLocation = locations[locationIndex];
			milesTraveled = currentLocation.getDistance();
			currentLocation.setVisited(true);
			locationIndex++;
			if(currentLocation.getLocationName().equals("Oregon")){
				comm.ThrowGUIEvent(new WinEvent(this));
			}
			else{
				comm.ThrowGUIEvent(new AtLocationEvent(currentLocation));
			}
		}
	}
}
